package com.yin.webmvc;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.Map;

public class HandlerAdapter {

    private Map<String,Integer> paramMapping;

    public HandlerAdapter(Map<String,Integer> paramMapping){
        this.paramMapping = paramMapping;
    }
    public ModelAndView handle(HttpServletRequest req, HttpServletResponse resp, HandlerMapping mapping) throws Exception{
        Class[] paramTypes = mapping.getMethod().getParameterTypes();
        Map<String,String[]> reqParameterMap = req.getParameterMap();
        Object[] paramValues = new Object[paramTypes.length];
        for (Map.Entry<String,String[]> entry : reqParameterMap.entrySet()){
            String value = Arrays.toString(entry.getValue()).replaceAll("\\[|\\]","").replaceAll("\\s","");
            if(!this.paramMapping.containsKey(entry.getKey())) continue;
            int index = this.paramMapping.get(entry.getKey());
            paramValues[index] = caseStringValue(value,paramTypes[index]);
        }
        if(this.paramMapping.containsKey(HttpServletRequest.class.getName())){
            int reqIndex =  this.paramMapping.get(HttpServletRequest.class.getName());
            paramValues[reqIndex] = req;
        }
        if(this.paramMapping.containsKey(HttpServletResponse.class.getName())){
            int respIndex = this.paramMapping.get(HttpServletResponse.class.getName());
            paramValues[respIndex] = resp;
        }

        Object result = mapping.getMethod().invoke(mapping.getController(),paramValues);
        if(result == null) return null;
        boolean isModelAndView = mapping.getMethod().getReturnType() == ModelAndView.class;
        if(!isModelAndView){
            return null;
        }else {
            return (ModelAndView)result;
        }
    }

    private Object caseStringValue(String value, Class<?> clazz){
        if(clazz == String.class){
            return value;
        }else if(clazz == Integer.class){
            return Integer.valueOf(value);
        }else if(clazz == int.class){
            return Integer.valueOf(value).intValue();
        }else {
            return null;
        }
    }
}
